﻿// *************************************************************************************************
// Project: RealSense.Light.Extensions
// Namespace: RealSense.Light.Extensions.Behaviors
// File: SpeechSynthesizerBehavior.cs  Author: Peter O'Hanlon
// Copyright © Peter O'Hanlon 2014-2015
// Date: 2015/1/6 22:36
// *************************************************************************************************
using RealSense.Light.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace RealSense.Light.Extensions.Behaviors
{
  public class SpeechSynthesizerBehavior : Behavior<FrameworkElement>
  {
    private static ISpeechSynthesizer speechSynthesizer;
    private static ISpeechSynthesizerValidation validator;

    public SpeechSynthesizerBehavior()
    {
      if (ResolutionContext.Resolver == null)
      {
        return;
      }
      speechSynthesizer = ResolutionContext.Resolver.Resolve<ISpeechSynthesizer>();
    }

    private static ISpeechSynthesizerValidation Validator
    {
      get
      {
        if (DesignTimeSupport.IsInDesigner)
        {
          return null;
        }
        if (validator == null)
          validator = ResolutionContext.Resolver.Resolve<ISpeechSynthesizerValidation>();
        return validator;
      }
    }

    #region SayText
    public static string GetSayText(DependencyObject obj)
    {
      return (string)obj.GetValue(SayTextProperty);
    }

    public static void SetSayText(DependencyObject obj, string value)
    {
      obj.SetValue(SayTextProperty, value);
    }

    public static readonly DependencyProperty SayTextProperty =
      DependencyProperty.RegisterAttached("SayText", typeof(string), typeof(SpeechSynthesizerBehavior),
      new UIPropertyMetadata(string.Empty, TextChanged));
    #endregion

    public static readonly DependencyProperty VolumeProperty =
      DependencyProperty.RegisterAttached("Volume", typeof(int), typeof(SpeechSynthesizerBehavior),
      new UIPropertyMetadata(80), new ValidateValueCallback(IsValidVolume));

    private static bool IsValidVolume(object value)
    {
      if (DesignTimeSupport.IsInDesigner)
      {
        return true;
      }
      int volume = (int)value;
      return Validator.IsValidVolume(volume);
    }

    public static void SetVolume(DependencyObject obj, int value)
    {
      obj.SetValue(VolumeProperty, value);
    }

    public static int GetVolume(DependencyObject obj)
    {
      return (int)obj.GetValue(VolumeProperty);
    }

    public static readonly DependencyProperty PitchProperty =
      DependencyProperty.RegisterAttached("Pitch", typeof(int), typeof(SpeechSynthesizerBehavior),
      new UIPropertyMetadata(100), new ValidateValueCallback(IsValidPitch));

    private static bool IsValidPitch(object value)
    {
      if (DesignTimeSupport.IsInDesigner)
      {
        return true;
      }
      int pitch = (int)value;
      return Validator.IsValidPitch(pitch);
    }

    public static void SetPitch(DependencyObject obj, int value)
    {
      obj.SetValue(PitchProperty, value);
    }

    public static int GetPitch(DependencyObject obj)
    {
      return (int)obj.GetValue(PitchProperty);
    }

    public static readonly DependencyProperty SpeechRateProperty =
      DependencyProperty.RegisterAttached("SpeechRate", typeof(int), typeof(SpeechSynthesizerBehavior),
      new UIPropertyMetadata(100), new ValidateValueCallback(IsValidSpeechRate));

    private static bool IsValidSpeechRate(object value)
    {
      if (DesignTimeSupport.IsInDesigner)
      {
        return true;
      }
      int speechRate = (int)value;
      return Validator.IsValidSpeechRate(speechRate);
    }

    public static void SetSpeechRate(DependencyObject obj, int value)
    {
      obj.SetValue(SpeechRateProperty, value);
    }

    public static int GetSpeechRate(DependencyObject obj)
    {
      return (int)obj.GetValue(SpeechRateProperty);
    }

    private static void TextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
      if (DesignTimeSupport.IsInDesigner)
      {
        return;
      }
      string speech = e.NewValue.ToString();
      if (string.IsNullOrWhiteSpace(speech)) return;

      DependencyObject dp = (DependencyObject)sender;
      int pitch = GetPitch(dp);
      int volume = GetVolume(dp);
      int rate = GetSpeechRate(dp);

      // Note - we will add the module later.
      speechSynthesizer
        .SetPitch(pitch)
        .SetVolume(volume)
        .SetSpeechRate(rate)
        .Say(e.NewValue.ToString());
    }
  }
}